/**
 * @author jjw
 * @type {{$on: pub.$on, $receive: pub.$receive, $pub: pub.$pub, list: {}, temporaryData: {}, $un: pub.$un, $emit: pub.$emit, $send: pub.$send}}
 */

// 定义一个发布者对象
// 处理后续促销
const pub = {
    // 缓存列表，存放订阅者回调函数
    list: {},
    // 订阅方法
    $on: function(key, fn) {
        // 如果没有该消息的缓存列表，就创建一个空数组
        if (!this.list[key]) {
            this.list[key] = [];
        }
        // 将回调函数推入该消息的缓存列表
        this.list[key].push(fn);
    },
    // 取消订阅方法
    $un: function(key, fn) {
        // 如果有该消息的缓存列表
        if (this.list[key]) {
            // 遍历缓存列表
            for (var i = this.list[key].length - 1; i >= 0; i--) {
                // 如果存在该回调函数，就从缓存列表中删除
                if (this.list[key][i] === fn) {
                    this.list[key].splice(i, 1);
                }
            }
        }
    },
    // 发布方法
    $pub: function() {
        // 获取消息类型
        const key = Array.prototype.shift.call(arguments);
        // 获取该消息的缓存列表
        const fns = this.list[key];
        // 如果没有订阅该消息，就返回
        if (!fns || fns.length === 0) {
            return;
        }
        // 遍历缓存列表，执行回调函数
        for (var i = 0; i < fns.length; i++) {
            fns[i].apply(this, arguments);
        }
    },
    //一次性发布通知后移除回调
    $emit: function() {
        // 获取消息类型
        const key = Array.prototype.shift.call(arguments);
        // 获取该消息的缓存列表
        const fns = this.list[key];
        // 如果没有订阅该消息，就返回
        if (!fns || fns.length === 0) {
            return;
        }
        // 遍历缓存列表，执行回调函数
        let fn;
        console.log(fns)
        while (fn = fns.shift()) {
            fn.apply(this, arguments)
        };
    },
    //清空订阅
    $remove: function(key) {
        Reflect.deleteProperty(this.list,key)
    },
    //发送后信息如果没有接收方则存在内存
    //先有发送才有接收方
    //节省内存5秒后自动销毁防止页面错误导致内存溢出
    temporaryData: {},
    $send:function () {
        const key = Array.prototype.shift.call(arguments);
        this.temporaryData[key] = arguments[0]
        setTimeout(()=>{
            if(this.temporaryData[key] === arguments[0]){
                Reflect.deleteProperty(this.temporaryData,key)
            }
        },1000)
    },
    $receive: function (key,fun) {
        const arg = this.temporaryData[key];
        if(arg){
            fun(arg)
            //清理内存
            Reflect.deleteProperty(this.temporaryData,key)
        }else{
            throw Error('未找到对象')
        }
    }
};
export default pub;